package cn.mazexal.examapi.common.config;


import cn.mazexal.examapi.common.filter.CredentialsInterceptor;

import com.alibaba.fastjson2.JSONWriter;
import com.alibaba.fastjson2.support.config.FastJsonConfig;
import com.alibaba.fastjson2.support.spring6.http.converter.FastJsonHttpMessageConverter;
import jakarta.annotation.Resource;
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import jakarta.validation.ValidatorFactory;
import org.hibernate.validator.HibernateValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.List;

/**
 * Web 配置
 *
 * @author Lay
 * @date 2024/2/29
 */
@Configuration
@ControllerAdvice
public class WebConfig implements WebMvcConfigurer {


    @Resource
    CredentialsInterceptor credentialsInterceptor;

    private static final String[] SWAGGER_EXCLUDE_PATHS = {
            "/v3/api-docs/**",
            "/swagger-resources/**",
            "/swagger-ui/**",
            "/webjars/**",
            "/doc.html"
    };

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(credentialsInterceptor).excludePathPatterns("/error").excludePathPatterns(SWAGGER_EXCLUDE_PATHS);
    }

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();

        // FastJson Config
        FastJsonConfig config = new FastJsonConfig();
        config.setDateFormat("yyyy-MM-dd HH:mm:ss");

        // writer features
        config.setWriterFeatures(
                // show null fields
                // JSONWriter.Feature.WriteNulls,
                // write default value replace of null
                // Number: null to 0
                // String: null to ""
                // Boolean: null to false
                // Array: null to []
                // JSONWriter.Feature.NullAsDefaultValue,
                JSONWriter.Feature.WriteNullListAsEmpty,
                // JSONWriter.Feature.WriteNullNumberAsZero,
                JSONWriter.Feature.WriteNullBooleanAsFalse,
                // write BigDecimal to Plain
                JSONWriter.Feature.WriteBigDecimalAsPlain,
                JSONWriter.Feature.WriteLongAsString,
                // avoid javascript integer out of range
                JSONWriter.Feature.BrowserCompatible,
                JSONWriter.Feature.WriteEnumsUsingName
        );

        // writer filters

        converter.setFastJsonConfig(config);
        converter.setDefaultCharset(StandardCharsets.UTF_8);
        converter.setSupportedMediaTypes(Collections.singletonList(MediaType.APPLICATION_JSON));
        converters.addFirst(converter);
    }

    @Bean
    public Validator validator() {
        try (ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class).configure().failFast(true).buildValidatorFactory()) {
            return validatorFactory.getValidator();
        } catch (Exception ignored) {
        }
        return null;
    }
}
